﻿using Datos.Interfaces;
using Entidad;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Dapper;
using DapperExtensions;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace Datos.Repositories
{
    public class ProveedorRepository : IProveedorRepository
    {
        private readonly Microsoft.Practices.EnterpriseLibrary.Data.Database _db;


        static ProveedorRepository()
        {
            //DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory(), false);
        }

        public ProveedorRepository()
        {
            _db = DatabaseFactory.CreateDatabase("RealConnection");
        }


        public IList<Proveedor> FindAll()
        {
            using(IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"SELECT * FROM Proveedor p
                                        JOIN TipoIva t ON t.Id = p.IdTipoIva
                                        JOIN Ciudad c ON c.Id = p.IdCiudad
                                        JOIN Actividad a ON a.Id = p.IdActividad
                                        JOIN Estado e ON e.Id = p.IdEstado";

                var datos = conn.Query<Proveedor, TipoIva, Ciudad, Actividad, Estado, Proveedor>
                    (query, (proveedor, tipoiva, ciudad, actividad, estado) =>
                {
                    proveedor.TipoIva = tipoiva; 
                    proveedor.Ciudad = ciudad;
                    proveedor.Actividad = actividad;
                    proveedor.Estado = estado;

                return proveedor;
                });
            
                return datos.ToList();
            }
        }

        public IQueryable<Proveedor> Find(Expression<Func<Proveedor, bool>> predicate)
        {
            throw new NotImplementedException();
        }

        public Proveedor FindById(int id)
        {            
            Proveedor prov;
            using(IDbConnection conn = _db.CreateConnection())
            {
               string query = @"SELECT * FROM Proveedor p
                                        JOIN TipoIva t ON t.Id = p.IdTipoIva
                                        JOIN Ciudad c ON c.Id = p.IdCiudad
                                        JOIN Actividad a ON a.Id = p.IdActividad
                                        JOIN Estado e ON e.Id = p.IdEstado
                                        WHERE p.Id = @id";

               prov = conn.Query<Proveedor, TipoIva, Ciudad, Actividad, Estado, Proveedor>
                   (query, (proveedor, tipoiva, ciudad, actividad, estado) =>
                   {
                       proveedor.TipoIva = tipoiva;
                       proveedor.Ciudad = ciudad;
                       proveedor.Actividad = actividad;
                       proveedor.Estado = estado;

                       return proveedor;

                   }, new { id = id}).SingleOrDefault();
               
            }
            return prov;
        }


        public int Add(Proveedor newEntity)
        {
            using (IDbConnection conn = _db.CreateConnection())
            {
            
                const string query = @"INSERT INTO Proveedor(RazonSocial, NombreFantasia,
                                        NumeroCuit, NumeroIngresosBrutos, IdTipoIva,
                                        Calle, Numeracion, Piso, Departamento, Barrio,
                                        CodigoPostal, Telefono, Email, IdCiudad, IdActividad,
                                        IdEstado)
                                       VALUES (
                                        @razonsocial, @nombrefantasia, @numerocuit,
                                        @numeroingresosbrutos, @idtipoiva, @calle,
                                        @numeracion, @piso, @departamento, @barrio,
                                        @codigopostal, @telefono, @email, @idciudad,
                                        @idactividad, @idestado)";

                return conn.Execute(query, new
                {
                    newEntity.RazonSocial,
                    newEntity.NombreFantasia,
                    newEntity.NumeroCuit,
                    newEntity.NumeroIngresosBrutos,
                    idTipoIva = newEntity.TipoIva.Id,
                    newEntity.Calle,
                    newEntity.Numeracion,
                    newEntity.Piso,
                    newEntity.Departamento,
                    newEntity.Barrio,
                    newEntity.CodigoPostal,
                    newEntity.Telefono,
                    newEntity.Email,
                    idCiudad = newEntity.Ciudad.Id,                    
                    idActividad = newEntity.Actividad.Id,
                    idEstado = newEntity.Estado.Id,
                });
                
            }
        }

        public bool Remove(int id)
        {
            bool resultado = false;
            using(IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"UPDATE Proveedor SET IdEstado = 2
                                        WHERE Id = @id";

                int filasAfectadas = conn.Execute(query, new { 
                    id = id,
                });

                if (filasAfectadas > 0)
                    resultado = true;
            }

            return resultado;
        }

        public int Modify(Proveedor entity)
        {
            using(IDbConnection conn = _db.CreateConnection())
            {
                string query = @"UPDATE Proveedor
                                SET RazonSocial = @razonsocial, NombreFantasia = @nombrefantasia,
                                NumeroCuit = @numerocuit, NumeroIngresosBrutos = @numeroingresosbrutos,
                                IdTipoIva = @idtipoiva, Calle = @calle, Numeracion = @numeracion, Piso = @piso,
                                Departamento = @departamento, Barrio = @barrio, CodigoPostal = @codigopostal,
                                Telefono = @telefono, Email = @email, IdCiudad = @idciudad, IdActividad = @idactividad,
                                IdEstado = @idestado
                                WHERE Id = @id";

                return conn.Execute(query, new
                {
                    razonsocial = entity.RazonSocial,
                    nombrefantasia = entity.NombreFantasia,
                    numerocuit = entity.NumeroCuit,
                    numeroingresosbrutos = entity.NumeroIngresosBrutos,
                    idtipoiva = entity.TipoIva.Id,
                    calle = entity.Calle,
                    numeracion = entity.Numeracion,
                    piso = entity.Piso,
                    departamento = entity.Departamento,
                    barrio = entity.Barrio,
                    codigopostal = entity.CodigoPostal,
                    telefono = entity.Telefono,
                    email = entity.Email,
                    idciudad = entity.Ciudad.Id,
                    idactividad = entity.Actividad.Id,
                    idestado = entity.Estado.Id,
                    id = entity.Id,
                });
            }
        }

        public IList<Proveedor> FindByRazonSocial(string razonSocial)
        {
            using (IDbConnection conn = _db.CreateConnection())
            {
                string query = @"SELECT * FROM Proveedor p
                                        JOIN TipoIva t ON t.Id = p.IdTipoIva
                                        JOIN Ciudad c ON c.Id = p.IdCiudad
                                        JOIN Actividad a ON a.Id = p.IdActividad
                                        JOIN Estado e ON e.Id = p.IdEstado
                                        WHERE p.RazonSocial LIKE '" + razonSocial + "'";

                var datos = conn.Query<Proveedor, TipoIva, Ciudad, Actividad, Estado, Proveedor>
                    (query, (proveedor, tipoiva, ciudad, actividad, estado) =>
                    {
                        proveedor.TipoIva = tipoiva;
                        proveedor.Ciudad = ciudad;
                        proveedor.Actividad = actividad;
                        proveedor.Estado = estado;

                        return proveedor;
                    });

                return datos.ToList();
            }
        }

    }
}
